# -*- coding:utf-8 -*-

from manufacturer.models import AlarmMsg, StatusMsg, AuthorityCode, ElevatorMalfunction, \
    ElevatorMalfunctionPersonRelation,  RepairContent, \
    ElevatorStatus, ElevatorFault,  \
    RepairContentElevatorMalfunctionRelation, RepairType, ContentCosts, CompanyPlatform, Manufacturer, \
    CompanyPlatformManufacturerRelation, ElevatorFaultAnalysis, MaterialForFault, AuthorityCodeUserRelation, User
from utils.views import WdListAPIView, WdListCreateAPIView, WdRetrieveUpdateAPIView, WdDestroyAPIView, WdAPIView,\
    WdRetrieveAPIView
from serializer import ElevatorFaultSerializer, StatusMsgSerializer, ElevatorMalfunctionListSerializer, \
    ElevatorMalfunctionSerializer, RepairContentSerializer, RepairTypeSerializer, \
    StatusMonitorListSerializer, StatusMonitorSerializer, \
    ElevatorFaultListSerializer, \
    ElevatorMalfunctionDetailSerializer, AuthorityCodeSerializer, AuthorityCodeListSerializer, CompanyPlatformSerializer, \
    ManufacturerSerializer, ManufacturerForPlatformSerializer, ElevatorFaultAnalysisSerializer
from django.db.models import Q, F
import operator
from basic.models import ElevatorInfo, ElevatorFollowedByUser
from utils.response import general_json_response, ErrorCode
from rest_framework import status
import datetime
from users.models import Person, CompanyInfo, Organization, OrganizationElevatorRelation, AuthUser
import json
import csv
from django.http import HttpResponse
from ElevatorAdmin.settings import RLHOST, THRESHOLD, IS_WX_CITY_CENTER
from utils.request_rl import handler_single_monitor_for_status, handler_multi_monitor_for_status
from utils.get_codes import get_registers
from maintenance.models import Task


def get_months():
    l = list()
    now = datetime.datetime.now()
    month = now.month
    year = now.year
    for i in range(10, -2, -1):
        m = month - i
        if m > 0:
            y = year
        else:
            m = m + 12
            y = year - 1
        l.append(datetime.datetime(year=y, month=m, day=1))
    return l


def num_check(jump_layer, half_layer, start_floor):
    l = []
    m = []
    if jump_layer:
        # 跳层
        ll = jump_layer.split(";")
        for s in ll:
            try:
                j, k = s.split("~")
                j = int(j)
                k = int(k)
                if not j <= k:
                    print 1
                    return False, ""
                l.extend(list(range(j, k + 1)))
            except Exception as e:
                print 2
                return False, ""
        if len(l) != len(set(l)):
            print 3
            return False, ""
        l.sort()
        if not start_floor <= l[0]:
            return False, ""
    if half_layer:
        mm = half_layer.split(";")
        for s in mm:
            try:
                j, k = s.split("~")
                j = int(j)
                k = int(k)
                if not j + 1 == k:
                    print 4
                    return False, ""
                m.append(j)
            except Exception as e:
                print 5
                return False, ""
        if len(m) != len(set(m)):
            print 6
            return False, ""
        m.sort()
        if not start_floor <= m[0]:
            return False, ""
    if l and m:
        max_num = l[-1] if l[-1] > m[-1] else m[-1]
    elif l and not m:
        max_num = l[-1]
    elif not l and m:
        max_num = m[-1]
    else:
        max_num = 0

    numbers = []
    if max_num:
        print jump_layer
        numbers = list(range(start_floor, max_num + 2))
        numbers = [i for i in numbers if i not in l and i != 0]
        for i in m:
            numbers.append(i + 0.5)
        numbers.sort()
        print numbers
    s = ",".join([str(i) for i in numbers]) if numbers else ""
    return True, s


def get_registers(user):
    u""" 非各个角色的管理员才会调用 """
    from users.models import OrganizationElevatorRelation, OrganizationAdminRoRelation, ElevatorAdminRoRelation, \
        AuthUserElevatorRelation
    if user.permission_type == 20:
        codes = AuthUserElevatorRelation.objects.filter_active(auth_user=user).values_list("register_code", flat=True).distinct()
        return codes
    admin_role = user.admin_role
    codes = list()
    if not admin_role:
        return codes
    if admin_role.management_type == 20:
        codes = ElevatorAdminRoRelation.objects.filter_active(admin_role=admin_role).values_list("register_code", flat=True).distinct()
        return codes
    oarr = OrganizationAdminRoRelation.objects.filter_active(admin_role=admin_role).first()
    if not oarr:
        return codes
    org = oarr.organization
    if not org:
        return codes
    codes = OrganizationElevatorRelation.objects.filter_active(organization=org).values_list("register_code", flat=True).distinct()
    return codes


class AlarmMsgListView(WdListAPIView):
    model = ElevatorFault
    serializer_class = ElevatorFaultSerializer

    def qs_search(self, qs):
        u"""REF: restframe work SearchFilter"""
        codes = self.request.GET.get("codes", "")
        if codes is None or not codes:
            return qs
        search_sql = []
        codes = codes.split(",")
        for code in codes:
                search_sql.append(Q(**{"a__contains": code}))
        if len(search_sql) == 0:
            return qs
        else:
            query = reduce(operator.or_, search_sql)
            qs = qs.filter(query)
        return qs

    def qs_business_role(self, qs):
        t = self.request.GET.get("today", None)
        if t:
            today = datetime.date.today()
            now = datetime.datetime(year=today.year, month=today.month, day=today.day)
            qs = qs.filter(create_time__gte=now)
        user = self.request.user
        role = user.role
        if role == 0:
            pass
        elif role == 10:
            qs = qs.none()
        elif role == 20:
            com = user.company_person.company
            acs = AuthorityCode.objects.filter_active(maintain_company=com).values_list("device_code_elevator", flat=True).distinct()
            qs = qs.filter(o__in=acs)
        elif role == 30:
            com = user.company_person.company
            acs = AuthorityCode.objects.filter_active(property_company=com).values_list("device_code_elevator", flat=True).distinct()
            qs = qs.filter(o__in=acs)
        return qs

    def qs_filter_by_ele(self, qs):
        user = self.request.user
        role = user.role
        if role == 0:
            return qs
        if user.role in [20, 30] and user.company_person.is_admin:
            return qs
        codes = self.get_registers()
        acs = AuthorityCode.objects.filter_active(elevator_code__in=codes).values_list(
            "device_code_elevator", flat=True).distinct()
        qs = qs.filter(o__in=acs)
        return qs

    def qs_filter(self, qs):
        register_code = self.request.GET.get("register_code", None)
        qs = super(AlarmMsgListView, self).qs_filter(qs)
        if register_code:
            acs = AuthorityCode.objects.filter_active(elevator_code__contains=register_code).values_list("device_code_elevator", flat=True).distinct()
            qs = qs.filter(o__in=acs)
        follow = self.request.GET.get("follow", None)
        if follow == u"1":
            eis = ElevatorFollowedByUser.objects.filter_active(user=self.request.user).values_list("elevator_id", flat=True).distinct()
            rgs = ElevatorInfo.objects.filter_active(id__in=eis).values_list("register_code", flat=True).distinct()
            acs = AuthorityCode.objects.filter_active(elevator_code__in=rgs).values_list("device_code_elevator", flat=True).distinct()
            qs = qs.filter(o__in=acs)
        frequent = self.request.GET.get("frequent", None)
        if frequent:
            ios = []
            acs = AuthorityCode.objects.filter_active().values_list("device_code_elevator", flat=True).distinct()
            for o in acs:
                sub_qs = ElevatorFault.objects.filter_active(o=o)
                if sub_qs.count() < 5:
                    continue
                alarm_time = None
                for sq in sub_qs.order_by("-id")[:5]:
                    if alarm_time:
                        if not alarm_time - sq.create_time < datetime.timedelta(days=1):
                            continue
                    alarm_time = sq.create_time
                ios.append(o)
            qs = qs.filter(o__in=ios)
        return qs


class AlarmsStatisticsListView(WdListAPIView):

    def get(self, request, *args, **kwargs):
        user = self.request.user
        role = user.role
        org = self.request.GET.get("org", None)
        org_type = self.request.GET.get("org_type", None)
        name = self.request.GET.get("name", None)
        page = self.request.GET.get("page", "1")
        page = int(page)
        page_size_count = self.request.GET.get("page_size_count", "8")
        page_size_count = int(page_size_count)
        qs = ElevatorFault.objects.filter_active()
        # 日 1; 月 2; 季度 3 ; 年 4
        granularity = self.request.GET.get("granularity", "1")
        time_from = self.request.GET.get("time_from", None)
        time_to = self.request.GET.get("time_to", None)
        key_words = self.request.GET.get("key_words", None)
        if key_words:
            aos = AuthorityCode.objects.filter_active(Q(elevator_code__icontains=key_words) | Q(manufacturer_code_elevator__icontains=key_words) | Q(device_code_elevator__icontains=key_words)).values_list("device_code_elevator", flat=True).distinct()
            qs = qs.filter(o__in=aos)
        now = datetime.datetime.now()
        month = datetime.datetime(year=now.year, month=now.month, day=1)
        if not time_from and not time_to:
            qs = qs.filter(create_time__gte=month)
            tf = month
            to = now
        elif not time_from and time_to:
            qs = qs.filter(create_time__lte=time_to)
            tf = ElevatorFault.objects.filter_active().first().create_time
            to = datetime.datetime.strptime(time_to, "%Y-%m-%d %H:%M:%S")
        elif not time_to and time_from:
            qs = qs.filter(create_time__gte=time_from)
            tf = datetime.datetime.strptime(time_from, "%Y-%m-%d %H:%M:%S")
            to = now
        else:
            qs = qs.filter(create_time__gte=time_from, create_time__lt=time_to)
            tf = datetime.datetime.strptime(time_from, "%Y-%m-%d %H:%M:%S")
            to = datetime.datetime.strptime(time_to, "%Y-%m-%d %H:%M:%S")
        if role == 0:
            if org and org_type and org != -1:
                com = CompanyInfo.objects.get(id=org)
                company_type = com.company_type
                if company_type == 100:
                    aos = AuthorityCode.objects.filter_active(maintain_company=com).values_list("device_code_elevator", flat=True).distinct()
                    qs = qs.filter(o__in=aos)
                else:
                    aos = AuthorityCode.objects.filter_active(property_company=com).values_list("device_code_elevator", flat=True).distinct()
                    qs = qs.filter(o__in=aos)
        elif role == 20:
            company = user.company_person.company
            aos = AuthorityCode.objects.filter_active(maintain_company=company).values_list("device_code_elevator", flat=True).distinct()
            qs = qs.filter(o__in=aos)
            if org and org_type:
                if org_type == "1":
                    com = CompanyInfo.objects.get(id=org)
                    company_type = com.company_type
                    if company_type == 300:
                        aos = AuthorityCode.objects.filter_active(property_company=com).values_list("device_code_elevator", flat=True).distinct()
                        qs = qs.filter(o__in=aos)
                elif org_type == "2":
                    organization = Organization.objects.get(id=org)
                    register_codes = OrganizationElevatorRelation.objects.filter_active(organization=organization).values_list("register_code", flat=True).distinct()
                    aos = AuthorityCode.objects.filter_active(elevator_code__in=register_codes).values_list("device_code_elevator", flat=True).distinct()
                    qs = qs.filter(o__in=aos)
        elif role == 30:
            if org_type == "2":
                organization = Organization.objects.get(id=org)
                register_codes = OrganizationElevatorRelation.objects.filter_active(organization=organization).values_list("register_code", flat=True).distinct()
                aos = AuthorityCode.objects.filter_active(elevator_code__in=register_codes).values_list("device_code_elevator", flat=True).distinct()
                qs = qs.filter(o__in=aos)

        if granularity == "1":
            threshold = (to - tf).days
        elif granularity == "2":
            threshold = (to - tf).days / 30
        elif granularity == "3":
            threshold = (to - tf).days / 90
        elif granularity == "4":
            threshold = (to - tf).days / 365
        else:
            threshold = 0
        if threshold > THRESHOLD:
            return general_json_response(status.HTTP_200_OK, ErrorCode.THRESHOLD_WRONG)
        ret = []
        day = tf
        # {"外设": [v1, v2, v3]}
        ws = dict()
        while day <= to:
            next_day = day + datetime.timedelta(days=1)
            sub_qs = qs.filter(create_time__lt=next_day, create_time__gte=day)
            value1 = 0
            value2 = 0
            value3 = 0
            value4 = 0
            value5 = 0
            value6 = 0
            value7 = 0
            value8 = 0
            value9 = 0
            value10 = 0
            value11 = 0
            value12 = 0
            value13 = 0
            value14 = 0
            value15 = 0
            value16 = 0
            for sq in sub_qs:
                s = sq.a
                s = s.split(",")
                if sq.o not in ws:
                    ac = AuthorityCode.objects.filter_active(device_code_elevator=sq.o).first()
                    ws[sq.o] = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ac.maintain_company_id if ac else 0, ac.property_company_id if ac else 0]]
                if "1" in s:
                    value1 += 1
                    ws[sq.o][0][0] += 1
                if "2" in s:
                    value2 += 1
                    ws[sq.o][0][1] += 1
                if "3" in s:
                    value3 += 1
                    ws[sq.o][0][2] += 1
                if "4" in s:
                    value4 += 1
                    ws[sq.o][0][3] += 1
                if "5" in s:
                    value5 += 1
                    ws[sq.o][0][4] += 1
                if "6" in s:
                    value6 += 1
                    ws[sq.o][0][5] += 1
                if "7" in s:
                    value7 += 1
                    ws[sq.o][0][6] += 1
                if "8" in s:
                    value8 += 1
                    ws[sq.o][0][7] += 1
                if "9" in s:
                    value9 += 1
                    ws[sq.o][0][8] += 1
                if "10" in s:
                    value10 += 1
                    ws[sq.o][0][9] += 1
                if "11" in s:
                    value11 += 1
                    ws[sq.o][0][10] += 1
                if "12" in s:
                    value12 += 1
                    ws[sq.o][0][11] += 1
                if "13" in s:
                    value13 += 1
                    ws[sq.o][0][12] += 1
                if "14" in s:
                    value14 += 1
                    ws[sq.o][0][13] += 1
                if "15" in s:
                    value15 += 1
                    ws[sq.o][0][14] += 1
                if "16" in s:
                    value16 += 1
                    ws[sq.o][0][15] += 1
            ret.append({"date": str(day), "value1": value1, "value2": value2, "value3": value3, "value4": value4,
                        "value5": value5, "value6": value6, "value7": value7, "value8": value8,
                        "value9": value9, "value10": value10, "value11": value11, "value13": value13,
                        "value14": value14, "value15": value15, "value16": value16, "value12": value12,
                        })
            day = next_day

        ws = {k: ws[k] for k in ws if ws[k][0] != [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}
        res = []
        if org and org_type:
            res = [{"org": org, "org_type": org_type, "name": name, "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}]
        else:
            if user.role == 0:
                coms = CompanyInfo.objects.filter_active(service_id=F("id"))
                for com in coms:
                    res.append({"org": com.id, "name": com.name, "org_type": "1", "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]})
            elif user.role == 20:
                company = user.company_person.company
                coms = CompanyInfo.objects.filter_active(service_id=company.id, company_type=300)
                for com in coms:
                    res.append({"org": com.id, "name": com.name, "org_type": "1", "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]})
                orgs = Organization.objects.filter_active(company=company)
                for org in orgs:
                    res.append({"org": org.id, "name": org.name, "org_type": "2", "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]})
            elif user.role == 30:
                company = user.company_person.company
                orgs = Organization.objects.filter_active(company=company)
                for org in orgs:
                    res.append({"org": org.id, "name": org.name, "org_type": "2", "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]})
        for key in ws:
            for org in res:
                if org['org_type'] == "1":
                    if org['org'] in ws[key][1]:
                        org['value'][0] += ws[key][0][0]
                        org['value'][1] += ws[key][0][1]
                        org['value'][2] += ws[key][0][2]
                        org['value'][3] += ws[key][0][3]
                        org['value'][4] += ws[key][0][4]
                        org['value'][5] += ws[key][0][5]
                        org['value'][6] += ws[key][0][6]
                        org['value'][7] += ws[key][0][7]
                        org['value'][8] += ws[key][0][8]
                        org['value'][9] += ws[key][0][9]
                        org['value'][10] += ws[key][0][10]
                        org['value'][11] += ws[key][0][11]
                        org['value'][12] += ws[key][0][12]
                        org['value'][13] += ws[key][0][13]
                        org['value'][14] += ws[key][0][14]
                        org['value'][15] += ws[key][0][15]
                        continue
                elif org['org_type'] == "2":
                    if AuthorityCode.belong_to_organization(key, int(org['org'])):
                        org['value'][0] += ws[key][0][0]
                        org['value'][1] += ws[key][0][1]
                        org['value'][2] += ws[key][0][2]
                        org['value'][3] += ws[key][0][3]
                        org['value'][4] += ws[key][0][4]
                        org['value'][5] += ws[key][0][5]
                        org['value'][6] += ws[key][0][6]
                        org['value'][7] += ws[key][0][7]
                        org['value'][8] += ws[key][0][8]
                        org['value'][9] += ws[key][0][9]
                        org['value'][10] += ws[key][0][10]
                        org['value'][11] += ws[key][0][11]
                        org['value'][12] += ws[key][0][12]
                        org['value'][13] += ws[key][0][13]
                        org['value'][14] += ws[key][0][14]
                        org['value'][15] += ws[key][0][15]

        res = [item for item in res if item['value'] != [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
        count = len(res)
        start = (page - 1) * page_size_count
        end = page * page_size_count
        data = {"list": res[start: end], "histogram": ret, "count": count}
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)


class OrganizationForAlarmsListView(WdListAPIView):

    def get(self, request, *args, **kwargs):
        user = self.request.user
        ret = list()
        # org_type 0 梯联网平台；1 单位； 2 组织
        if user.role == 0:
            ret.append({"org": -1, "name": u"梯联网平台", "org_type": "0"})
            coms = CompanyInfo.objects.filter_active(service_id=F("id"))
            for com in coms:
                ret.append({"org": com.id, "name": com.name, "org_type": "1"})
        elif user.role == 20:
            company = user.company_person.company
            ret.append({"org": company.id, "name": company.name, "org_type": "1"})
            coms = CompanyInfo.objects.filter_active(service_id=company.id, company_type=300)
            for com in coms:
                ret.append({"org": com.id, "name": com.name, "org_type": "1"})
            orgs = Organization.objects.filter_active(company=company)
            for org in orgs:
                ret.append({"org": org.id, "name": org.name, "org_type": "2"})
        elif user.role == 30:
            company = user.company_person.company
            ret.append({"org": company.id, "name": company.name, "org_type": "1"})
            orgs = Organization.objects.filter_active(company=company)
            for org in orgs:
                ret.append({"org": org.id, "name": org.name, "org_type": "2"})
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, ret)


class StatusMstListView(WdListAPIView):
    model = StatusMsg
    serializer_class = StatusMsgSerializer

    def get_queryset(self):
        qs = StatusMsg.objects.filter_active()
        elevators = self.request.GET.get("elevators", None)
        if not elevators:
            return qs.none()
        elevators = elevators.split(",")
        register_codes = ElevatorInfo.objects.filter_active(id__in=elevators).values_list("register_code", flat=True).distinct()
        qs = qs.filter(authority_code__elevator_code__in=register_codes)
        return qs


class AlarmMstStatisticsView(WdListAPIView):

    def get(self, request, *args, **kwargs):
        months = get_months()
        l = list()
        m = list()
        data = list()
        codes = self.get_registers()
        for i in range(12):
            dic = dict()
            if i == 11:
                count = AlarmMsg.objects.filter(create_time__gte=months[11], authority_code__elevator_code__in=codes).count()
            else:
                count = AlarmMsg.objects.filter(create_time__gte=months[i], create_time__lt=months[i + 1], authority_code__elevator_code__in=codes).count()
            dic["month"] = months[i].strftime("%Y-%m-%d")
            dic['count'] = count
            l.append(dic)
        data.append({"statistics": l})
        m.append({"code": u'轿厢报警按钮', "count": AlarmMsg.objects.filter(is_alarm=1, authority_code__elevator_code__in=codes).count()})
        m.append({"code": u'电梯困人', "count": AlarmMsg.objects.filter(is_trapped=1, authority_code__elevator_code__in=codes).count()})
        m.append({"code": u'非平层停梯', "count": AlarmMsg.objects.filter(stop_abnormal=1, authority_code__elevator_code__in=codes).count()})
        m.append({"code": u'安全回路断路', "count": AlarmMsg.objects.filter(circuit_break=1, authority_code__elevator_code__in=codes).count()})
        m.append({"code": u'轿厢冲顶', "count": AlarmMsg.objects.filter(is_top=1, authority_code__elevator_code__in=codes).count()})
        m.append({"code": u'轿厢蹲底', "count": AlarmMsg.objects.filter(is_bottom=1, authority_code__elevator_code__in=codes).count()})
        m.append({"code": u'开门走梯', "count": AlarmMsg.objects.filter(go_with_open=1, authority_code__elevator_code__in=codes).count()})
        m.sort(key=lambda k: k['count'], reverse=True)
        data.append({"alarm": m})
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)


class ElevatorMalfunctionListCreateView(WdListCreateAPIView, WdDestroyAPIView):

    model = ElevatorMalfunction
    serializer_class = ElevatorMalfunctionListSerializer
    p_serializer_class = ElevatorMalfunctionSerializer
    FILTER_FIELDS = ("maintenance_type", "status")
    # SEARCH_FIELDS = ("register_code", )
    POST_DATA_ID_RESPONSE = True
    POST_DATA_RESPONSE = True
    POST_CHECK_REQUEST_PARAMETER = ("register_code", "person", "start_planning_time", "end_planning_time",
                                    "maintenance_type")

    def post_check_parameter(self, kwargs):
        code = super(ElevatorMalfunctionListCreateView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        register_code = self.request.data.get("register_code")
        elevator = ElevatorInfo.objects.filter_active(register_code=register_code).first()
        pro_no = elevator.factory_no
        ac = AuthorityCode.objects.filter_active(elevator_code=elevator.register_code).first()
        factory_code = ac.manufacturer_code if ac else None
        per_unique_code = ac.device_code if ac else None
        alarm_time = None
        person = self.request.data.get("person", [])
        persons = Person.objects.filter_active(id__in=person)
        person_names = [p.auth_user.real_name for p in persons]
        notify_person = ",".join(person_names)
        if ac:
            alarm = ac.alarm_msg.all().order_by("-id").first()
            if alarm:
                alarm_time = alarm.create_time.date()
        equ_loc_addr = elevator.property_company.register_address
        s = 10
        now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        time_points = json.dumps({"10": now})
        self.request.data.update({
            "notify_person": notify_person,
            "service_id": elevator.service_id,
            "elevator": elevator.id,
            "pro_no": pro_no,
            "factory_code": factory_code,
            "per_unique_code": per_unique_code,
            "alarm_time": alarm_time,
            "equ_loc_addr": equ_loc_addr,
            "status": s,
            "time_points": time_points,
            "maintain_company": elevator.maintain_company.id,
            "property_company": elevator.property_company.id,
            "maintain_company_name": elevator.maintain_company.name,
            "property_company_name": elevator.property_company.name,
        })
        return code

    def qs_filter_by_ele(self, qs):
        user = self.request.user
        if user.username == u"admin":
            return qs
        if user.role in [20, 30] and user.company_person.is_admin:
            return qs
        codes = self.get_registers()
        qs = qs.filter(register_code__in=codes)
        return qs

    def qs_filter(self, qs):
        qs = super(ElevatorMalfunctionListCreateView, self).qs_filter(qs)
        time_to = self.request.GET.get("time_to", None)
        time_from = self.request.GET.get("time_from", None)
        register_code = self.request.GET.get("register_code", None)
        time_status = self.request.GET.get("time_status", None)
        today = datetime.date.today()
        three_days_later = today + datetime.timedelta(days=3)
        t = self.request.GET.get("today", None)
        if t:
            qs = qs.filter(end_planning_time=today)
        if register_code:
            qs = qs.filter(register_code__icontains=register_code)
        if time_from:
            qs = qs.filter(start_planning_time__gte=time_from)
        if time_to:
            qs = qs.filter(start_planning_time__lte=time_to)
        if time_status == u"10":
            qs = qs.filter(end_planning_time__lt=today, status__lt=50)
        elif time_status == u"20":
            qs = qs.filter(end_planning_time__gte=today, end_planning_time__lte=three_days_later, status__lt=50)
        elif time_status == u"30":
            qs = qs.exclude(end_planning_time__lte=three_days_later, status__lt=50)
        elif time_status == u"40":
            qs = qs.filter(status__in=(0, 10))
        follow = self.request.GET.get("follow", None)
        if follow == u"1":
            eis = ElevatorFollowedByUser.objects.filter_active(user=self.request.user).values_list("elevator",
                                                                                                   flat=True).distinct()
            qs = qs.filter(elevator__in=eis)
        return qs

    def perform_create(self, serializer):
        create_obj = serializer.save()
        elevator_malfunction_id = serializer.data.get("id")
        person = self.request.data.get("person", [])
        content = self.request.data.get("content", []) # [{"repair_content_id": xx, "number": 4}, {}]
        service_id = serializer.data.get("service_id", 0)
        buck_list = list()
        for p in person:
            obj = ElevatorMalfunctionPersonRelation(elevator_malfunction_id=elevator_malfunction_id, person_id=p,
                                                    service_id=service_id)
            buck_list.append(obj)
        ElevatorMalfunctionPersonRelation.objects.bulk_create(buck_list)

        buck_list = list()
        money = 0
        for c in content:
            obj = RepairContentElevatorMalfunctionRelation(elevator_malfunction_id=elevator_malfunction_id,
                                                           service_id=service_id, repair_content_id=c["repair_content_id"],
                                                           number=c["number"])
            m = obj.repair_content.content_costs.all().first()
            if m:
                money += m.costs * c["number"]
            buck_list.append(obj)
        RepairContentElevatorMalfunctionRelation.objects.bulk_create(buck_list)
        user = self.request.user
        service_id = user.company_person.service_id
        com = CompanyInfo.objects.get(id=service_id)
        hour_price = com.hour_price
        create_obj.costs = money + hour_price * create_obj.work_hours
        create_obj.save()

    def delete(self, request, *args, **kwargs):
        ids = self.request.data.get("ids", [])
        self.model.objects.filter_active(id__in=ids).update(is_active=False)
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)


class ElevatorFaultCreateElevatorMalfunction(WdAPIView):

    def post(self, request, *args, **kwargs):
        fault = self.request.data.get("fault", None)

        if not fault:
            return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, u"id是必传项")
        ef = ElevatorFault.objects.get(id=fault)
        dic = {"status": 1, "register_code": ef.e, "per_unique_code": ef.o, "create_user": self.request.user}
        ac = AuthorityCode.objects.filter_active(device_code_elevator=ef.o).first()
        if ac:
            dic['maintain_company'] = ac.maintain_company
            dic['maintain_company_name'] = ac.maintain_company.name if ac.maintain_company else None
            dic['property_company'] = ac.property_company
            dic['property_company_name'] = ac.property_company.name if ac.property_company else None
        ElevatorMalfunction.objects.update_or_create(fault_id=fault, defaults=dic)
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)


class ElevatorMalfunctionDetailView(WdRetrieveUpdateAPIView, WdDestroyAPIView):

    model = ElevatorMalfunction
    serializer_class = ElevatorMalfunctionDetailSerializer
    p_serializer_class = ElevatorMalfunctionSerializer
    POST_DATA_ID_RESPONSE = True
    POST_DATA_RESPONSE = True

    def post_check_parameter(self, kwargs):
        code = super(ElevatorMalfunctionDetailView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        elevator_malfunction_id = self.get_id()
        au = self.request.data.get("audited", None)
        register_code = self.request.data.get("register_code")
        elevator = ElevatorInfo.objects.filter_active(register_code=register_code).first()
        pro_no = elevator.factory_no
        ac = AuthorityCode.objects.filter_active(elevator_code=elevator.register_code).first()
        factory_code = ac.manufacturer_code if ac else None
        per_unique_code = ac.device_code if ac else None
        equ_loc_addr = elevator.property_company.register_address
        self.request.data.update({
            "service_id": elevator.service_id,
            "elevator": elevator.id,
            "pro_no": pro_no,
            "factory_code": factory_code,
            "per_unique_code": per_unique_code,
            "equ_loc_addr": equ_loc_addr,
            "maintain_company": elevator.maintain_company.id,
            "property_company": elevator.property_company.id,
            "maintain_company_name": elevator.maintain_company.name,
            "property_company_name": elevator.property_company.name,
        })
        if au:
            if self.get_object().time_points:
                tp = json.loads(self.get_object().time_points)
                tp.update({"10": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
                tp = json.dumps(tp)
            else:
                tp = json.dumps({"10": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
            self.request.data.update({"time_points": tp})
            self.request.data.update({"status": 10})
        person = self.request.data.get("person", [])
        content = self.request.data.get("content", [])  # [{"repair_content_id": xx, "number": 4}, {}]
        service_id = self.get_object().service_id
        if person:
            ps = ElevatorMalfunctionPersonRelation.objects.filter_active(elevator_malfunction_id=elevator_malfunction_id).values_list("person_id", flat=True).distinct()
            if sorted(person) != sorted(ps):
                name = []
                ElevatorMalfunctionPersonRelation.objects.filter_active(elevator_malfunction_id=elevator_malfunction_id).update(is_active=False)
                buck_list = list()
                for p in person:
                    obj = ElevatorMalfunctionPersonRelation(elevator_malfunction_id=elevator_malfunction_id,
                                                            person_id=p,
                                                            service_id=service_id)
                    buck_list.append(obj)
                    name.append(obj.person.auth_user.real_name)
                ElevatorMalfunctionPersonRelation.objects.bulk_create(buck_list)
                self.request.data.update({"notify_person": ",".join(name)})

        if content:
            cs = RepairContentElevatorMalfunctionRelation.objects.filter_active(elevator_malfunction_id=elevator_malfunction_id).values("repair_content_id", "number")
            if sorted(content) != sorted(cs):
                money = 0
                RepairContentElevatorMalfunctionRelation.objects.filter_active(
                    elevator_malfunction_id=elevator_malfunction_id).update(is_active=False)
                buck_list = list()
                for c in content:
                    obj = RepairContentElevatorMalfunctionRelation(elevator_malfunction_id=elevator_malfunction_id,
                                                                   service_id=service_id, number=c["number"],
                                                                   repair_content_id=c["repair_content_id"])
                    buck_list.append(obj)
                    m = obj.repair_content.content_costs.first()
                    if m and m.costs:
                        money += m.costs * c["number"]
                RepairContentElevatorMalfunctionRelation.objects.bulk_create(buck_list)
                self.request.data.update({"costs": money})
        return code

    def perform_destroy(self, instance):
        super(ElevatorMalfunctionDetailView, self).perform_destroy(instance)
        elevator_malfunction_id = self.get_id()
        ElevatorMalfunctionPersonRelation.objects.filter_active(elevator_malfunction_id=elevator_malfunction_id).update(
            is_active=False)
        RepairContentElevatorMalfunctionRelation.objects.filter_active(
            elevator_malfunction_id=elevator_malfunction_id).update(is_active=False)


class ElevatorMalfunctionDownload(WdAPIView):

    def get(self, request, *args, **kwargs):
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="users.csv"'
        writer = csv.writer(response)
        l = [u'电梯注册号', u'维修类型', u'报修时间', u'状态', u'维保单位', u'使用单位', u'维修人员', u'计划开始时间', u'计划完成时间', u'工时', u'预估费用']
        l = [i.encode('utf8') for i in l]
        writer.writerow(l)
        company = self.request.user.company_person.company
        ems = ElevatorMalfunction.objects.filter_active(service_id=company.id)
        for em in ems:
            alarm_time = em.alarm_time
            at = alarm_time.strftime("%Y-%m-%d %H:%M:%S") if alarm_time else " "
            m = [em.register_code, em.get_maintenance_type_display(), at, em.get_status_display(), em.maintain_company.name if em.maintain_company else " ", em.property_company.name if em.property_company else " ", em.notify_person if em.notify_person else " ",
                 str(em.start_planning_time) if em.start_planning_time else " ", str(em.end_planning_time) if em.end_planning_time else " ", str(em.work_hours), str(em.costs)]
            m = [i.encode('utf8') for i in m]
            writer.writerow(m)
        return response


class RepairContentListCreateView(WdListCreateAPIView):
    """ 维修项目"""
    model = RepairContent
    serializer_class = RepairContentSerializer
    FILTER_FIELDS = ("repair_type",)
    POST_DATA_RESPONSE = True
    POST_DATA_ID_RESPONSE = True
    SEARCH_FIELDS = ("content", )
    FOREIGN_SEARCH_FIELD_MAP = {'id': [ContentCosts, 'name']}  # {'model_id': [ResearchModel, 'name']}

    def process_foreign_search(self):
        key_words = self.request.GET.get(self.SEARCH_KEY, None)
        search_sql = []
        for key_name in self.FOREIGN_SEARCH_FIELD_MAP:
            search_info = self.FOREIGN_SEARCH_FIELD_MAP[key_name]
            foreign_cls = search_info[0]
            foreign_field = search_info[1]
            ids = foreign_cls.objects.filter(**{"%s__icontains" % foreign_field: key_words}).values_list("repair_content_id", flat=True).distinct()
            search_sql.append(Q(**{"%s__in" % key_name: ids}))
        return search_sql

    def qs_search(self, qs):
        u"""REF: restframe work SearchFilter"""

        key_words = self.request.GET.get(self.SEARCH_KEY, None)
        if key_words is None or not key_words:
            return qs
        search_sql = []
        for search_field in self.SEARCH_FIELDS:
            search_sql.append(Q(**{"%s__icontains" % search_field: key_words}))
        search_sql += self.process_foreign_search()
        if len(search_sql) == 0:
            return qs
        else:
            query = reduce(operator.or_, search_sql)
            qs = qs.filter(query)
        return qs

    def post_check_parameter(self, kwargs):
        code = super(RepairContentListCreateView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        name = self.request.data.get("name", None)
        user = self.request.user
        if user.role == 0:
            service_ids = (0, )
        elif user.role == 20:
            service_id = user.company_person.company.id
            service_ids = (0, service_id)
        else:
            service_ids = (0, )
        b = ContentCosts.objects.filter_active(name=name, service_id__in=service_ids).exists()
        if b:
            code = ErrorCode.NAME_EXISTED
        return code

    def qs_business_role(self, qs):
        user = self.request.user
        if user.role == 0:
            return qs
        elif user.role == 20:
            com = user.company_person.company
            qs = qs.filter(service_id__in=(com.id, 0))
        else:
            qs = qs.none()
        return qs

    def perform_create(self, serializer):
        super(RepairContentListCreateView, self).perform_create(serializer)
        costs = self.request.data.get("costs", 0)
        name = self.request.data.get("name", None)
        ContentCosts.objects.create(repair_content_id=serializer.data.get("id"), costs=costs, name=name,
                                    service_id=serializer.data.get("service_id"))


class RepairContentDetailView(WdRetrieveUpdateAPIView, WdDestroyAPIView):
    """ 维修项目"""
    model = RepairContent
    serializer_class = RepairContentSerializer
    POST_DATA_RESPONSE = True
    POST_DATA_ID_RESPONSE = True

    def put(self, request, *args, **kwargs):
        if self.partial:
            rsp = self.partial_update(request, *args, **kwargs)
        else:
            rsp = self.update(request, *args, **kwargs)
        costs = self.request.data.get("costs", None)
        name = self.request.data.get("name", None)
        if name:
            user = self.request.user
            if user.role == 0:
                service_id = 0
            else:
                service_id = user.company_person.company.service_id
            cc = ContentCosts.objects.filter_active(repair_content=self.get_object(), service_id=service_id).first()
            service_ids = (0, service_id)
            b = ContentCosts.objects.filter_active(service_id__in=service_ids, name=name).exclude(id=cc.id).exists()
            if b:
                return general_json_response(status.HTTP_200_OK, ErrorCode.NAME_EXISTED)
        ContentCosts.objects.update_or_create(repair_content_id=self.get_id(), service_id=self.get_object().service_id, defaults={"costs": costs, "name": name})
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)

    def perform_destroy(self, instance):
        if self.OBJECT_WITH_ACTIVE:
            instance.is_active = False
            instance.save()
        else:
            instance.delete()
        cc = ContentCosts.objects.filter_active(repair_content_id=self.get_id())
        if cc:
            cc.update(is_active=False)


class RepairTypeListCreateView(WdListCreateAPIView):
    """ 维修类型 """
    model = RepairType
    serializer_class = RepairTypeSerializer
    SEARCH_FIELDS = ("name", )

    def qs_business_role(self, qs):
        user = self.request.user
        if user.role == 0:
            return qs
        elif user.role == 20:
            com = user.company_person.company
            qs = qs.filter(service_id__in=(com.id, 0))
        else:
            qs = qs.none()
        return qs


class RepairDetailView(WdRetrieveUpdateAPIView, WdDestroyAPIView):
    """ 维修类型 """
    model = RepairType
    serializer_class = RepairTypeSerializer
    SEARCH_FIELDS = ("name", )

    def post_check_parameter(self, kwargs):
        code = super(RepairDetailView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        if self.request.user.role != 0 and self.get_object().service_id == 0:
            return ErrorCode.PERMISSION_FAIL
        return code

    def delete_check_parameter(self, kwargs):
        code = super(RepairDetailView, self).delete_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        if self.request.user.role != 0 and self.get_object().service_id == 0:
            return ErrorCode.PERMISSION_FAIL
        return code


class StatusMonitorListView(WdListAPIView):

    model = AuthorityCode
    serializer_class = StatusMonitorListSerializer

    def qs_filter(self, qs):
        qs = super(StatusMonitorListView, self).qs_filter(qs)
        # l = ElevatorInfo.objects.filter_active(~Q(manufacturer_company=None), ~Q(factory_no=None))
        l = ElevatorInfo.objects.filter_active(~Q(factory_no=''), manufacturer_company__isnull=False)
        user = self.request.user
        if user.role == 0:
            pass
        elif user.role in (10, 20, 30, 40):
            if user.role == 10 or not user.company_person.is_admin:
                service_id = user.service_id
                l = l.filter(service_id=service_id)
                codes = get_registers(user)
                l = l.filter(register_code__in=codes)
            else:
                service_id = user.company_person.company.service_id
                l = l.filter(service_id=service_id)
        else:
            l = l.none()
        m = []
        for ei in l:
            m.append({"manufacturer_code": ei.manufacturer_company.code, "manufacturer_number": ei.factory_no})
        ids = []
        for dic in m:
            ac = AuthorityCode.objects.filter_active(manufacturer_code_elevator=dic['manufacturer_code'], manufacturer_number_elevator=dic['manufacturer_number']).first()
            if ac:
                ids.append(ac.id)
        qs = qs.filter(id__in=ids)
        is_online = self.request.GET.get("is_online", None)
        if is_online == "1":
            qs = qs.filter(is_online=True)
        elif is_online == "0":
            qs = qs.filter(is_online=False)
        follow = self.request.GET.get("follow", None)
        if follow:
            ids = AuthorityCodeUserRelation.objects.filter_active(user=user).values_list("authority_code_id", flat=True).distinct()
            qs = qs.filter(id__in=ids)
        return qs

    def qs_business_role(self, qs):
        return qs

    def qs_search(self, qs):
        u"""REF: restframe work SearchFilter"""
        search_sql = []
        elevator_code = self.request.GET.get("e", None)
        if elevator_code:
            search_sql.append(Q(**{"elevator_code__icontains": elevator_code}))
        address = self.request.GET.get("address", None)
        if address:
            search_sql.append(Q(**{"address__icontains": address}))
        device_code_elevator = self.request.GET.get("o", None)
        if device_code_elevator:
            search_sql.append(Q(**{"device_code_elevator__icontains": device_code_elevator}))
        if len(search_sql) == 0:
            return qs
        else:
            query = reduce(operator.or_, search_sql)
            qs = qs.filter(query)
        return qs


class AuthorityCodeUserRelationView(WdAPIView):

    def post(self, request, *args, **kwargs):
        user = self.request.user
        pk = self.request.data.get("id", None)
        follow = self.request.data.get("follow", None)
        is_active = True if follow else False
        AuthorityCodeUserRelation.objects.update_or_create(authority_code_id=pk, user=user, defaults={"is_active": is_active})
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)


class RequestToRLForStatusView(WdAPIView):

    GET_CHECK_REQUEST_PARAMETER = ("register_code", )

    def get(self, request, *args, **kwargs):
        from .models import User
        register_code = self.request.GET.get("register_code", None)
        ses = User.objects.filter_active().order_by("-id").first().session
        if IS_WX_CITY_CENTER:
            handler_single_monitor_for_status(register_code, ses, self.request.user.username)

        # url = RLHOST
        # url += "&regcode=" + register_code + "&ses=" + ses
        # res = requests.get(url)
        # SystemLog.objects.create(create_by=u"市民中心", log=url, log_type=2)
        # try:
        #     res = res.json()
        #     SystemLog.objects.create(create_by=u"市民中心", log=json.dumps(res, ensure_ascii=False), log_type=2)
        #     return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, res)
        # except Exception as e:
        #     print e
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)


class StatusMonitorRetrieveView(WdRetrieveAPIView):

    model = ElevatorStatus
    serializer_class = StatusMonitorSerializer


class StatusMonitorRetrieveViewV2(WdAPIView):

    model = AuthorityCode

    def get(self, request, *args, **kwargs):
        ac = self.get_object()
        o = ac.o()
        es = ElevatorStatus.objects.filter_active(o=o).first()
        ses = User.objects.filter_active().order_by("-id").first().session
        ei = ElevatorInfo.objects.filter_active(factory_no=ac.manufacturer_number_elevator, manufacturer_company=ac.manufacturer()).first()
        if IS_WX_CITY_CENTER:
            handler_single_monitor_for_status.delay(ac.elevator_code, ses, self.request.user.username)

        now = datetime.datetime.now()
        today = datetime.datetime(year=now.year, month=now.month, day=now.day)
        efs = ElevatorFault.objects.filter_active(o=o, create_time__gte=today).values_list("a", flat=True).distinct()
        l = list()
        for ef in efs:
            if ef:
                l.extend(ef.split(","))
        l = list(set(l))
        dic = {
            "1": u"轿厢报警按钮", "2": u"电梯困人", "3": u"非平层停梯", "4": u"安全回路断路",
            "5": u"轿厢冲顶", "6": u"轿厢蹲底", "7": u"开门走梯", "8": u"电梯速度异常", "9": u"电梯运行时安全回路断路",
            "10": u"关门故障", "11": u"开门故障", "12": u"轿厢在开锁区域外停止", "13": u"轿厢意外移动",
            "14": u"电动机运转时间限制器动作", "15": u"楼层位置丢失", "16": u"其他阻止电梯再启动的故障"
        }
        l = [{"code": k, "value": dic[k]} for k in l if k in dic]
        data = {
            "id": ac.id,
            "property_company_name": ac.property_company_name,
            "internal_no": ac.address,
            "cp": es.cp if es else None,
            "is_open": es.is_open() if es else None,
            "run_status": es.run_status() if es else None,
            "bend_times": ac.bend_times,  # 钢丝绳折弯次数
            "run_times": ac.run_times,  # 运行次数
            "open_times": ac.open_times,  # 开关门次数
            "up_time": ac.up_time,  # 运行时间
            "register_code": ei.register_code,
            "installation_place": ei.address or ei.installation_place,
            "last_checkup_time": ei.last_checkup_time(),
            "last_checkup_score": ei.last_checkup_score(),
            "manufacturer_company_name": ei.manufacturer_company_name,
            "alarms": l
        }
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)


class StatusMultiMonitorListView(WdListAPIView):

    # model = ElevatorStatus
    # serializer_class = StatusMonitorSerializer
    # GET_CHECK_REQUEST_PARAMETER = ("ids", )

    # def qs_filter(self, qs):
    #     ids = self.request.GET.get("ids", "")
    #     ids = ids.split(",")
    #     qs = super(StatusMultiMonitorListView, self).qs_filter(qs)
    #     qs = qs.filter(id__in=ids)
    #     return qs

    def get(self, request, *args, **kwargs):
        ids = self.request.GET.get("ids", "")
        ids = ids.split(",")
        data = []
        acs = AuthorityCode.objects.filter_active(id__in=ids)
        register_codes = acs.values_list("elevator_code", flat=True).distinct()
        ses = User.objects.filter_active().order_by("-id").first().session
        handler_multi_monitor_for_status.delay(list(register_codes), ses, self.request.user.username)
        for ac in acs:
            es = ElevatorStatus.objects.filter_active(o=ac.o()).first()
            ei = ElevatorInfo.objects.filter_active(factory_no=ac.manufacturer_number_elevator, manufacturer_company=ac.manufacturer()).first()
            data.append({
                "id": ac.id,
                "property_company_name": ac.property_company_name,
                "internal_no": ac.address,
                "cp": es.cp if es else None,
                "is_open": es.is_open() if es else None,
                "run_status": es.run_status() if es else None,
                "button_display": es.button_display() if es else "0",
                "register_code": ac.elevator_code or ei.register_code,
                "installation_place": ei.address or ei.installation_place,
                "last_checkup_time": ei.last_checkup_time(),
                "last_checkup_score": ei.last_checkup_score(),
                "manufacturer_company_name": ei.manufacturer_company_name,
                "surl": ac.surl,
            })
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)


class MonitorStatisticsView(WdAPIView):

    def get(self, request, *arg, **kwargs):
        pk = self.request.GET.get("id")
        ac = AuthorityCode.objects.get(id=int(pk))
        now = datetime.datetime.now()
        today = datetime.date.today()
        statistics = {
            "bend_times": ac.bend_times,  # 钢丝绳折弯次数
            "run_times": ac.run_times,  # 运行次数
            "open_times": ac.open_times,  # 开关门次数
            "up_time": ac.up_time,  # 运行时间
        }
        elevator = ElevatorInfo.objects.filter_active(register_code=ac.elevator_code).first()
        pre_task = None
        next_task = None
        if elevator:
            pre_task = Task.objects.filter_active(elevator=elevator, task_end_time__lte=now).order_by("-id").first()
            next_task = Task.objects.filter_active(day__gte=today, task_end_time__isnull=True).first()
        maintenance = {
            "company": elevator.maintain_company_name if elevator else "",
            "pre_task": pre_task.task_end_time.strip("%Y-%m-%d") if pre_task else "",
            "next_task": str(next_task.day) if next_task else "",
            "person": pre_task.maintainer_name if pre_task else "",
        }
        inspection = {
            "next_yearly_inspection_date": elevator.next_yearly_inspection_date if elevator else "",
            "inspection_conclusion": elevator.inspection_conclusion if elevator else "",
            "inspection_people": elevator.inspection_people if elevator else "",
        }

        data = {
            "statistics": statistics, "maintenance": maintenance, "inspection": inspection
        }

        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)


class MonitorBasicInfoView(WdAPIView):

    def get(self, request, *arg, **kwargs):
        pk = self.request.GET.get("id")
        ac = AuthorityCode.objects.get(id=int(pk))
        elevator = ElevatorInfo.objects.filter_active(register_code=ac.elevator_code).first()
        data = {
            "register_code": elevator.register_code if elevator else "",                    # 注册代码
            "elevator_type": elevator.get_elevator_type_display() if elevator else "",      # 电梯类型
            "elevator_name": elevator.elevator_name if elevator else "",                    # 名称
            "factory_no": elevator.factory_no if elevator else "",                          # 出场编号
            "elevator_model": elevator.elevator_model if elevator else "",               # 电梯型号
            "registry_status": elevator.get_registry_status_display() if elevator else "",  # 注册状态
            "num": elevator.num if elevator else "",                                        # 96333
            "registry_time": elevator.registry_time if elevator else "",                    # 注册日期
            "manufacturer_company_name": elevator.manufacturer_company_name if elevator else "",   # 制造单位，
            "next_yearly_inspection_date": elevator.next_yearly_inspection_date if elevator else "",  # 到检日期
            "installation_place": elevator.installation_place if elevator else "",          # 使用地点
            "property_company_name": elevator.property_company_name if elevator else "",     # 使用单位
            "maintain_company_name": elevator.maintain_company_name if elevator else "",      # 维保单位
            "phone_num": elevator.phone_num if elevator else "",                                # 维保电话
            "inspection_company": elevator.inspection_company if elevator else "",              # 监察单位
        }
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)


class ElevatorFaultListView(WdListAPIView):

    model = ElevatorFault
    serializer_class = ElevatorFaultListSerializer
    GET_CHECK_REQUEST_PARAMETER = ("id", )

    def qs_filter(self, qs):
        alarm = self.request.GET.get("alarm", None)
        time_from = self.request.GET.get("time_from", None)
        time_to = self.request.GET.get("time_to", None)
        qs = super(ElevatorFaultListView, self).qs_filter(qs)
        s_id = self.request.GET.get("id", None)
        today = self.request.GET.get("today", None)
        au = AuthorityCode.objects.get(id=s_id)
        now = datetime.datetime.now()
        qs = qs.filter(o=au.o())
        if today:
            t = datetime.datetime(year=now.year, month=now.month, day=now.day)
            qs = qs.filter(create_time__gte=t)
        if time_from:
            qs = qs.filter(create_time__gte=time_from)
        if time_to:
            qs = qs.filter(create_time__gte=time_to)
        if alarm:
            ids = []
            for i in qs:
                if i.a:
                    l = i.a.split(",")
                    if alarm in l:
                        ids.append(i.id)
            qs = qs.filter(id__in=ids)
        return qs


class AuthorityCodeListCreateView(WdListCreateAPIView):

    model = AuthorityCode
    p_serializer_class = AuthorityCodeSerializer
    serializer_class = AuthorityCodeListSerializer
    FILTER_FIELDS = ("manufacturer_code_elevator", "elevator_type", "device_type")
    SEARCH_FIELDS = ("sim_no", "collection_num", "manufacturer_number_elevator", "maintain_company_name", "address",
                     "elevator_code", "property_company_name", "device_code_elevator")
    POST_DATA_ID_RESPONSE = True
    POST_DATA_RESPONSE = True

    def qs_filter(self, qs):
        qs = super(AuthorityCodeListCreateView, self).qs_filter(qs)
        user = self.request.user
        if user.role == 40:
            rg = ElevatorInfo.objects.filter_active(supervised=1).values_list("register_code", flat=True).distinct()
            qs = qs.filter(elevator_code__in=rg)
        return qs

    def post_check_parameter(self, kwargs):
        """ 格式 1~2;3~5;8~19 """
        code = super(AuthorityCodeListCreateView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        jump_layer = self.request.data.get("jump_layer", "")
        half_layer = self.request.data.get("half_layer", "")
        start_floor = self.request.data.get("start_floor", 1)
        b, layer = num_check(jump_layer, half_layer, start_floor)
        self.request.data.update({"layer": layer})
        if not jump_layer:
            self.request.data.update({"jump_layer": ""})
        if not half_layer:
            self.request.data.update({"half_layer": ""})
        if not layer:
            self.request.data.update({"layer": ""})
        if not b:
            code = ErrorCode.FLOOR_WRONG
        return code

    def perform_create(self, serializer):
        from call_interface import elevator_register
        super(AuthorityCodeListCreateView, self).perform_create(serializer)
        obj = self.create_obj
        obj.property_company_name = obj.property_company.name if obj.property_company else None
        obj.maintain_company_name = obj.maintain_company.name if obj.maintain_company else None
        obj.save()
        elevator_register.delay(obj.id)

    def qs_search(self, qs):
        u"""REF: restframe work SearchFilter"""

        search_sql = []
        for search_field in self.SEARCH_FIELDS:
            sf = self.request.GET.get("%s" % search_field, None)
            if sf:
                search_sql.append(Q(**{"%s__icontains" % search_field: sf}))

        # search_sql += self.process_foreign_search()
        # search_sql += self.process_tag_search(qs, key_words)

        if len(search_sql) == 0:
            return qs
        else:
            query = reduce(operator.or_, search_sql)
            qs = qs.filter(query)
        return qs


class AuthorityCodeDetailView(WdRetrieveUpdateAPIView, WdDestroyAPIView):
    model = AuthorityCode
    p_serializer_class = AuthorityCodeSerializer
    serializer_class = AuthorityCodeListSerializer
    POST_DATA_RESPONSE = True

    def post_check_parameter(self, kwargs):
        """ 格式 1~2;3~5;8~19 """
        code = super(AuthorityCodeDetailView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        jump_layer = self.request.data.get("jump_layer", "")
        half_layer = self.request.data.get("half_layer", "")
        start_floor = self.request.data.get("start_floor", 1)
        b, layer = num_check(jump_layer, half_layer, start_floor)
        self.request.data.update({"layer": layer})
        if not jump_layer:
            self.request.data.update({"jump_layer": ""})
        if not half_layer:
            self.request.data.update({"half_layer": ""})
        if not layer:
            self.request.data.update({"layer": ""})
        if not b:
            code = ErrorCode.FLOOR_WRONG
        return code

    def perform_update(self, serializer):
        super(AuthorityCodeDetailView, self).perform_update(serializer)
        obj = self.get_object()
        obj.property_company_name = obj.property_company.name if obj.property_company else None
        obj.maintain_company_name = obj.maintain_company.name if obj.maintain_company else None
        obj.save()


class CompanyForAuthorityCodeListView(WdListAPIView):

    def get(self, *args, **kwargs):
        maintain_company = CompanyInfo.objects.filter_active(company_type=100).values("id", "name")
        property_company = CompanyInfo.objects.filter_active(company_type=300).values("id", "name")
        ec = Manufacturer.objects.filter_active().values("name", "code")
        ec = [{"manufacturer_name": item['name'], "manufacturer_code_elevator": item['code']} for item in ec]
        l = {
            "maintain_company": maintain_company,
            "property_company": property_company,
            "ec": ec,
        }
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, l)


class ElevatorForAuthorityCodeListView(WdListAPIView):

    GET_CHECK_REQUEST_PARAMETER = ("register_code", )

    def get(self, *args, **kwargs):
        register_code = self.request.GET.get("register_code")
        l = ElevatorInfo.objects.filter_active(register_code__contains=register_code).values("id", "maintain_company", "maintain_company_name", "property_company", "property_company_name", "register_code", "elevator_type")
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, l)


class CompanyPlatformListCreateView(WdListCreateAPIView):

    model = CompanyPlatform
    serializer_class = CompanyPlatformSerializer
    SEARCH_FIELDS = ("name", )

    def perform_create(self, serializer):
        super(CompanyPlatformListCreateView, self).perform_create(serializer)
        obj = self.create_obj
        manus = self.request.data.get("manus", [])
        bulk_list = []
        manus = Manufacturer.objects.filter_active(id__in=manus)
        for manu in manus:
            bulk_list.append(CompanyPlatformManufacturerRelation(manufacturer=manu, company_platform=obj))
        if bulk_list:
            CompanyPlatformManufacturerRelation.objects.bulk_create(bulk_list)


class ManufacturerDownLoadView(WdAPIView):
    def get(self, request, *args, **kwargs):
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="users.csv"'
        writer = csv.writer(response)
        l = [u'厂商名称', u'品牌名称', u'厂家编号', u'地址', u'厂家电话', u'联系人', u'联系人电话']
        l = [i.encode('utf8') for i in l]
        writer.writerow(l)
        manus = Manufacturer.objects.filter_active()
        for manu in manus:
            m = [manu.name, manu.brand_name, manu.code, manu.address, manu.manu_phone, manu.contact, manu.contact_phone]
            m = [i.encode('utf8') for i in m]
            writer.writerow(m)
        return response


class CompanyPlatformDetailView(WdRetrieveUpdateAPIView, WdDestroyAPIView):

    model = CompanyPlatform
    serializer_class = CompanyPlatformSerializer

    def perform_update(self, serializer):
        super(CompanyPlatformDetailView, self).perform_update(serializer)
        manus = self.request.data.get("manus", [])
        cid = self.get_id()
        CompanyPlatformManufacturerRelation.objects.filter_active(company_platform_id=cid).update(is_active=False)
        bulk_list = []
        manus = Manufacturer.objects.filter_active(id__in=manus)
        for manu in manus:
            bulk_list.append(CompanyPlatformManufacturerRelation(manufacturer=manu, company_platform_id=cid))
        if bulk_list:
            CompanyPlatformManufacturerRelation.objects.bulk_create(bulk_list)


class ManufacturerForPlatformListView(WdListAPIView):

    model = Manufacturer
    serializer_class = ManufacturerForPlatformSerializer
    SEARCH_FIELDS = ("name", )


class ManufacturerListCreateView(WdListCreateAPIView):

    model = Manufacturer
    serializer_class = ManufacturerSerializer
    SEARCH_FIELDS = ("name", )

    def qs_business_role(self, qs):
        return qs


class ManufacturerDetailView(WdRetrieveUpdateAPIView, WdDestroyAPIView):

    model = Manufacturer
    serializer_class = ManufacturerSerializer


class ElevatorFaultAnalysisListCreateView(WdListCreateAPIView, WdDestroyAPIView):

    model = ElevatorFaultAnalysis
    serializer_class = ElevatorFaultAnalysisSerializer
    SEARCH_FIELDS = ("name", )
    FILTER_FIELDS = ("auth_user", "property_company")

    def post_check_parameter(self, kwargs):
        code = super(ElevatorFaultAnalysisListCreateView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        stime = self.request.data.get("stime", None)
        today = datetime.date.today().strftime("%Y-%m-%d")
        if not stime:
            self.request.data.update({"stime": today})
        return code

    def perform_create(self, serializer):
        super(ElevatorFaultAnalysisListCreateView, self).perform_create(serializer)
        obj = self.create_obj
        if obj.property_company:
            obj.property_company_name = obj.property_company.name
        if obj.auth_user:
            obj.username = obj.auth_user.username
        obj.save()
        materials = self.request.data.get("materials", [])
        bulk_list = []
        for dic in materials:
            mff = MaterialForFault(name=dic['name'], pictures=dic['pictures'], fault_analysis=obj)
            bulk_list.append(mff)
        MaterialForFault.objects.bulk_create(bulk_list)

    def qs_filter(self, qs):
        qs = super(ElevatorFaultAnalysisListCreateView, self).qs_filter(qs)
        time_from = self.request.GET.get("time_from", None)
        time_to = self.request.GET.get("time_to", None)
        if time_from:
            qs = qs.filter(stime__gte=time_from)
        if time_to:
            qs = qs.filter(stime_lte=time_to)
        return qs

    def delete(self, request, *args, **kwargs):
        ids = self.request.data.get("ids", [])
        ElevatorFaultAnalysis.objects.filter_active(id__in=ids).update(is_active=False)
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)


class ElevatorFaultAnalysisDetailView(WdRetrieveUpdateAPIView, WdDestroyAPIView):

    model = ElevatorFaultAnalysis
    serializer_class = ElevatorFaultAnalysisSerializer

    def perform_update(self, serializer):
        super(ElevatorFaultAnalysisDetailView, self).perform_update(serializer)
        obj = self.get_object()
        if obj.property_company:
            obj.property_company_name = obj.property_company.name
        else:
            obj.property_company_name = ""
        if obj.auth_user:
            obj.username = obj.auth_user.username
        else:
            obj.username = ""
        obj.save()
        MaterialForFault.objects.filter_active(fault_analysis=obj).update(is_active=False)
        materials = self.request.data.get("materials", [])
        bulk_list = []
        for dic in materials:
            mff = MaterialForFault(name=dic['name'], pictures=dic['pictures'], fault_analysis=obj)
            bulk_list.append(mff)
        MaterialForFault.objects.bulk_create(bulk_list)


class PersonsForElevatorFaultAnalysisListView(WdListAPIView):

    def get(self, request, *args, **kwargs):
        service_id = self.request.user.service_id
        role = self.request.user.role
        if role == 0:
            coms = CompanyInfo.objects.filter_active(company_type=300).values("id", "name")
            users = AuthUser.objects.filter(is_active=True).values("username", "id")
        else:
            coms = CompanyInfo.objects.filter_active(service_id=service_id, company_type=300).values("id", "name")
            users = AuthUser.objects.filter(is_active=True, service_id=service_id).values("username", "id")

        data = {"companys": coms, "users": users}
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)


class ElevatorFaultAnalysisDownLoadView(WdAPIView):
    def get(self, request, *args, **kwargs):
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="users.csv"'
        writer = csv.writer(response)
        l = [u'故障名称', u'故障类型', u'解决人', u'解决时间', u'使用单位', u'解决办法']
        l = [i.encode('utf8') for i in l]
        writer.writerow(l)
        qs = ElevatorFaultAnalysis.objects.filter_active()
        user = self.request.user
        if user.role != 0:
            service_id = user.service_id
            qs = qs.filter(service_id=service_id)
        for efa in qs:
            m = [efa.name, efa.etype, efa.username, efa.stime.strftime("%Y-%m-%d"), efa.property_company_name, efa.solution]
            m = [i.encode('utf8') for i in m]
            writer.writerow(m)
        return response


class ElevatorFaultPolling(WdAPIView):

    def get(self, request, *args, **kwargs):
        now = datetime.datetime.now()
        two_second_ago = now - datetime.timedelta(seconds=2)
        efs = ElevatorFault.objects.filter_active(create_time__gte=two_second_ago)
        user = self.request.user
        if user.role in (20, 30):
            codes = ElevatorInfo.objects.filter_active(service_id=user.service_id, register_code__isnull=False).values_list("register_code", flat=True).distinct()
            if not user.company_person.is_admin:
                codes = get_registers(user)
            aos = AuthorityCode.objects.filter_active(elevator_code__in=codes).values_list("device_code_elevator", flat=True).distinct()
            efs = efs.filter(o__in=aos)
        data = list()
        dic = {
            "1": u"轿厢报警按钮", "2": u"电梯困人", "3": u"非平层停梯", "4": u"安全回路断路",
            "5": u"轿厢冲顶", "6": u"轿厢蹲底", "7": u"开门走梯", "8": u"电梯速度异常", "9": u"电梯运行时安全回路断路",
            "10": u"关门故障", "11": u"开门故障", "12": u"轿厢在开锁区域外停止", "13": u"轿厢意外移动",
            "14": u"电动机运转时间限制器动作", "15": u"楼层位置丢失", "16": u"其他阻止电梯再启动的故障"
        }
        for ef in efs:
            alarm_list = list()
            alarms = ef.a
            if alarms:
                alarms = alarms.split(",")
                for al in alarms:
                    if dic.get(al):
                        alarm_list.append(dic.get(al))
            alarm = ",".join(alarm_list)
            if alarm:
                data.append(ef.address() + ef.create_time.strftime("%Y-%m-%d %H:%M:%S") + u", 发生电梯故障异常: " + alarm)
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)




























